﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seqex.Tests;
using System.Collections;
using PaperExamples.GraphTest;

namespace MicroBenchmarks.GraphTest
{
    public class MyList
    {
        private object[] objarr = new object[200];
        private int count = 0;

        public int Count
        {
            get
            {
                return count;
            }
        }

        public void Add(object o)
        {
            objarr[count++] = o;
        }

        public bool Contains(object o)
        {
            for (int i = 0; i < count; i++)
            {
                if (objarr[i] == o)
                    return true;
            }
            return false;
        }

        public IEnumerable<object> Iterate()
        {
            for (int i = 0; i < count; i++)
            {
                yield return objarr[i];
            }
        }
    }

    public interface GraphInterfaceExtended
        : GraphInterface
    {
    }
        
    /// <summary>
    /// Adjacency graph implementation based on hashset
    /// </summary>
    public class HashAdjacencyGraph : GraphInterfaceExtended
    {
        const int MAX_VERTICES = 3;
        const int MAX_EDGES = 5;
        private HashSet<Vertex> vertexList;
        private HashSet<Edge> edgeList;

        public int EdgeSetCnt
        {
            get
            {
                return edgeList.Count;
            }
        }

        public HashAdjacencyGraph()
        {
            this.vertexList = new HashSet<Vertex>();
            this.edgeList = new HashSet<Edge>();
        }

        public void AddMVertex(Vertex v)
        {
            if (v == null)
                throw new Exception("Vertex cannot be null");

            if (this.vertexList.Count == MAX_VERTICES)
            {
                Console.WriteLine("Graph full");
                return;
            }

            this.vertexList.Add(v);
        }

        private bool ContainsVertex(Vertex v)
        {
            return this.vertexList.Contains(v);
        }

        public Edge AddMEdge(Vertex v1, Vertex v2)
        {
            //if (this.edgeList.Count == MAX_EDGES)
            //    throw new Exception("Edges full");

            if (v1 == null || v2 == null)
                throw new Exception("Vertices are empty");

            if (v1 == v2)
                return null;

            if (!this.ContainsVertex(v1))
                return null;

            if (!this.vertexList.Contains(v2))
                return null;

            Edge edge = new Edge();
            edge.SetStart(v1);
            edge.SetEnd(v2);
            this.edgeList.Add(edge);
            return edge;
        }
    }
    
    /// <summary>
    /// AdjacencyGraph implementation based on arraylist
    /// </summary>
    public class MAdjacencyGraph : GraphInterface
    {        
        const int MAX_VERTICES = 3;
        const int MAX_EDGES = 5;
        private ArrayList vertexList;
        private ArrayList edgeList;

        public int EdgeSetCnt
        {
            get
            {
                return edgeList.Count;
            }
        }        

        public MAdjacencyGraph()
        {
            this.vertexList = new ArrayList();
            this.edgeList = new ArrayList();
        }        

        public void AddMVertex(Vertex v)
        {
            if (v == null)
                throw new Exception("Vertex cannot be null");

            if (this.vertexList.Count == MAX_VERTICES)
            {
                Console.WriteLine("Graph full");
                return;
            }

            this.vertexList.Add(v);
        }

        private bool ContainsVertex(Vertex v)
        {
            return this.vertexList.Contains(v);
        }

        public Edge AddMEdge(Vertex v1, Vertex v2)
        {
            //if (this.edgeList.Count == MAX_EDGES)
            //    throw new Exception("Edges full");

            if (v1 == null || v2 == null)
                throw new Exception("Vertices are empty");

            if (v1 == v2)
                return null;

            bool contains = this.vertexList.Contains(v1);
            if (!contains)
                return null;

            if (!this.vertexList.Contains(v2))
                return null;

            Edge edge = new Edge();
            edge.SetStart(v1);
            edge.SetEnd(v2);
            this.edgeList.Add(edge);
            return edge;
        }
    }
}
